columnview: Allow adding/removing columns
authorBenjamin Otte <otte@redhat.com>
Mon, 28 Oct 2019 19:50:49 +0000 (20:50 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 30 May 2020 23:26:46 +0000 (19:26 -0400)
... and make that work in UI files via <child>, too.

docs/reference/gtk/gtk4-sections.txt
docs/reference/gtk/meson.build
gtk/gtkcolumnview.c
gtk/gtkcolumnview.h
gtk/gtkcolumnviewcolumn.c
gtk/gtkcolumnviewcolumnprivate.h [new file with mode: 0644]

index 6838a9d9861892777cf084d69f1c7dc1113812ff..33c56fc807d10b198d31a2b78f429074599765d2 100644 (file)
@@ -477,6 +477,8 @@ gtk_list_view_get_type
 <TITLE>GtkColumnView</TITLE>
 GtkColumnView
 gtk_column_view_new
+gtk_column_view_append_column
+gtk_column_view_remove_column
 gtk_column_view_get_columns
 gtk_column_view_get_model
 gtk_column_view_set_model
index b0e685f64aa43ea478a256b6b9044cb7510f1108..aa1bfdf0578a23524c086d886eca325fdf0c69bf 100644 (file)
@@ -24,6 +24,7 @@ private_headers = [
   'gtkcolorplaneprivate.h',
   'gtkcolorscaleprivate.h',
   'gtkcolorswatchprivate.h',
+  'gtkcolumnviewcolumnprivate.h',
   'gtkcomboboxprivate.h',
   'gtkconstraintexpressionprivate.h',
   'gtkconstraintguideprivate.h',
index 63124085b54b4538d861bdc17a1c6246559a8fad..14dec39135eb371aaaa414b17d1db77ac63a551a 100644 (file)
@@ -22,7 +22,8 @@
 #include "gtkcolumnview.h"
 
 #include "gtkboxlayout.h"
-#include "gtkcolumnviewcolumn.h"
+#include "gtkbuildable.h"
+#include "gtkcolumnviewcolumnprivate.h"
 #include "gtkintl.h"
 #include "gtklistview.h"
 #include "gtkmain.h"
@@ -68,7 +69,41 @@ enum {
   LAST_SIGNAL
 };
 
-G_DEFINE_TYPE (GtkColumnView, gtk_column_view, GTK_TYPE_WIDGET)
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_column_view_buildable_add_child (GtkBuildable  *buildable,
+                                     GtkBuilder    *builder,
+                                     GObject       *child,
+                                     const gchar   *type)
+{
+  if (GTK_IS_COLUMN_VIEW_COLUMN (child))
+    {
+      if (type != NULL)
+        {
+          GTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type);
+        }
+      else
+        {
+          gtk_column_view_append_column (GTK_COLUMN_VIEW (buildable),
+                                         GTK_COLUMN_VIEW_COLUMN (child));
+        }
+    }
+  else
+    {
+      parent_buildable_iface->add_child (buildable, builder, child, type);
+    }
+}
+
+static void
+gtk_column_view_buildable_interface_init (GtkBuildableIface *iface)
+{
+  parent_buildable_iface = g_type_interface_peek_parent (iface);
+
+  iface->add_child = gtk_column_view_buildable_add_child;
+}
+G_DEFINE_TYPE_WITH_CODE (GtkColumnView, gtk_column_view, GTK_TYPE_WIDGET,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_column_view_buildable_interface_init))
 
 static GParamSpec *properties[N_PROPS] = { NULL, };
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -86,7 +121,12 @@ gtk_column_view_dispose (GObject *object)
 {
   GtkColumnView *self = GTK_COLUMN_VIEW (object);
 
-  g_list_store_remove_all (self->columns);
+  while (g_list_model_get_n_items (G_LIST_MODEL (self->columns)) > 0)
+    {
+      GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), 0);
+      gtk_column_view_remove_column (self, column);
+      g_object_unref (column);
+    }
 
   g_clear_pointer ((GtkWidget **) &self->listview, gtk_widget_unparent);
 
@@ -356,3 +396,57 @@ gtk_column_view_get_show_separators (GtkColumnView *self)
 
   return gtk_list_view_get_show_separators (self->listview);
 }
+
+/**
+ * gtk_column_view_append_column:
+ * @self: a #GtkColumnView
+ * @column: a #GtkColumnViewColumn that hasn't been added to a
+ *     #GtkColumnView yet
+ *
+ * Appends the @column to the end of the columns in @self.
+ **/
+void
+gtk_column_view_append_column (GtkColumnView       *self,
+                               GtkColumnViewColumn *column)
+{
+  g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
+  g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (column));
+  g_return_if_fail (gtk_column_view_column_get_column_view (column) == NULL);
+
+  gtk_column_view_column_set_column_view (column, self);
+  g_list_store_append (self->columns, column);
+}
+
+/**
+ * gtk_column_view_remove_column:
+ * @self: a #GtkColumnView
+ * @column: a #GtkColumnViewColumn that's part of @self
+ *
+ * Removes the @column from the list of columns of @self.
+ **/
+void
+gtk_column_view_remove_column (GtkColumnView       *self,
+                               GtkColumnViewColumn *column)
+{
+  guint i;
+
+  g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
+  g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (column));
+  g_return_if_fail (gtk_column_view_column_get_column_view (column) == self);
+
+  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++)
+    {
+      GtkColumnViewColumn *item = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
+
+      g_object_unref (item);
+      if (item == column)
+        {
+          gtk_column_view_column_set_column_view (column, NULL);
+          g_list_store_remove (self->columns, i);
+          return;
+        }
+    }
+
+  g_assert_not_reached ();
+}
+
index 2781c840525b6106890d6e338efc3e9f9615582f..a4ac08a8b14fe6a0b66ab6b07f83104fdee6c61c 100644 (file)
@@ -53,6 +53,13 @@ GtkWidget *     gtk_column_view_new                             (void);
 
 GDK_AVAILABLE_IN_ALL
 GListModel *    gtk_column_view_get_columns                     (GtkColumnView          *self);
+GDK_AVAILABLE_IN_ALL
+void            gtk_column_view_append_column                   (GtkColumnView          *self,
+                                                                 GtkColumnViewColumn    *column);
+GDK_AVAILABLE_IN_ALL
+void            gtk_column_view_remove_column                   (GtkColumnView          *self,
+                                                                 GtkColumnViewColumn    *column);
+
 GDK_AVAILABLE_IN_ALL
 GListModel *    gtk_column_view_get_model                       (GtkColumnView          *self);
 GDK_AVAILABLE_IN_ALL
index 6102fea09cb09c0bbda8abc2c36385a162e3374b..b500d7654fe1f55810e692da6103eee2e2fceada 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "config.h"
 
-#include "gtkcolumnviewcolumn.h"
+#include "gtkcolumnviewcolumnprivate.h"
 
 #include "gtkintl.h"
 #include "gtklistbaseprivate.h"
@@ -259,6 +259,18 @@ gtk_column_view_column_get_column_view (GtkColumnViewColumn *self)
   return self->view;
 }
 
+void
+gtk_column_view_column_set_column_view (GtkColumnViewColumn *self,
+                                        GtkColumnView       *view)
+{
+  if (self->view == view)
+    return;
+
+  self->view = view;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLUMN_VIEW]);
+}
+
 /**
  * gtk_column_view_column_get_factory:
  * @self: a #GtkColumnViewColumn
diff --git a/gtk/gtkcolumnviewcolumnprivate.h b/gtk/gtkcolumnviewcolumnprivate.h
new file mode 100644 (file)
index 0000000..fcdcdaa
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2019 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__
+#define __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__
+
+#include "gtk/gtkcolumnviewcolumn.h"
+
+void                    gtk_column_view_column_set_column_view          (GtkColumnViewColumn    *self,
+                                                                         GtkColumnView          *view);
+
+
+#endif  /* __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ */